package com.platform.comm.util;

import java.util.stream.Stream;

/**
 * Description: 尾递归函数接口
 *
 * @author libin
 * Created on 2019/5/17
 **/
public interface TailCall<T> {
    /**
     * 用于递归栈帧之间的连接，惰性求值
     *
     * @return 下一个递归栈帧
     */
    TailCall<T> apply();

    /**
     * 判断当前递归是否结束
     *
     * @return 默认false，正常的递归过程中都未结束
     */
    default boolean isComplete() {
        return false;
    }

    /**
     * 获得递归结果，只有在递归结束才能调用，这里默认给出异常，通过工具类的重写来获得值
     *
     * @return 递归最终结果
     */
    default T result() {
        throw new Error("not implemented");
    }

    /**
     * 及早求值，执行者一系列的递归因为栈帧只有一个，所以使用findFirst获得最终的栈帧，接着调用getResult方法获得最终递归值
     *
     * @return 递归最终结果
     */
    default T invoke() {
        return Stream.iterate(this, TailCall::apply)
                .filter(TailCall::isComplete)
                .findFirst()
                .get()
                .result();
    }
}
